package imagenes;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Point;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ColorConvertOp;
import java.awt.image.PixelGrabber;
import java.util.StringTokenizer;
import java.util.Vector;
import java.lang.Object;

import javax.media.jai.PlanarImage;
import javax.media.jai.TiledImage;
import javax.swing.ImageIcon;

public class ProcesamientoDeImagenes {
	
	/*]*
	 * lista de algoritmos cargados
	 * */
	private Vector listaAlgoritmos;
	public Image myimg = null;
	Graphics2D g;
	PlanarImage template = null;
	PlanarImage capturaTotal = null;
	
	/**algoritmo 1
	 * toma una imagen de color y la transforma en escala de grises
	 */
	
	public Image crearMosaico (Image im,int tamanio){
		BufferedImage comodin= this.toBufferedImage(im);
		if (im==null){
			System.out.println("im es nulo, ProcesamientoDeImagenes.crearMosaico");
			return null;
		}
		int posY=0;
		int posX = 0;
		int ancho =comodin.getWidth();
		int alto = comodin.getHeight();
		int altoCorte=0;
		int anchoCorte=0;
		int[] promedio = new int[3];
		for( int x=0; x < ancho; x++ ){
			if(posX>ancho){
				x=ancho;
			}
			for( int y=0; y  < alto; y++ ){
				posY= y * tamanio;
				posX= x * tamanio;
				if(posY>alto){
					y=alto;
				}if ((posY<alto)&&(posX<ancho)){
					anchoCorte = ancho - posX;
					altoCorte = alto - posY;
					if(anchoCorte>tamanio){
						anchoCorte=tamanio;
					}else if(anchoCorte ==0){
						anchoCorte=1;
					}
					if(altoCorte>tamanio){
						altoCorte=tamanio;
					}else if(altoCorte ==0){
						altoCorte=1;
			
					
					}
					System.out.println(
							"bloque usado "+posX+","+posY+
							" R="+promedio[0]+
							" G="+promedio[1]+
							" B="+promedio[2]+
							", largo de cortes " +altoCorte+" , "+anchoCorte);
					//promedio = this.colorPromedio(
//							this.recortarImagenSeleccion(
//									posX, posY, anchoCorte, altoCorte, im));
//					ImagePanel ip = new ImagePanel();
//					im=ip.pintarBloque(posX, posY, anchoCorte, altoCorte, im,promedio);
				}				
			}
		}
		return im;
	}

//	public long implemTempRasters(PlanarImage imagen, PlanarImage template){
//		long t0, t1;
//        t0 =  System.currentTimeMillis();
//		TemplateMatchingWithRasters tmr = new TemplateMatchingWithRasters(imagen, template); 
//		tmr.templateMatch();
//		tmr.listarCandidatos();
//		t1 =  System.currentTimeMillis();
//		return t1-t0;
//	}
//	
	public void setTemplate(PlanarImage paratemplate){
		this.template = paratemplate;
	}
	
	public PlanarImage getTemplate(){
		return this.template;
	}
	
//	public Vector GetCandTempRaster(PlanarImage imagen, PlanarImage template){
//		TemplateMatchingWithRasters tmr = new TemplateMatchingWithRasters(imagen, template); 
//		tmr.templateMatch();
//		return tmr.getCanditatos();
//	} 
	
//    public Point GetPuntoTempRaster(PlanarImage imagen, PlanarImage template){
//    	TemplateMatchingWithRasters tmr = new TemplateMatchingWithRasters(imagen, template); 
//		tmr.templateMatch();
//		String candidato1 = tmr.getCanditatos().get(0).toString();
//		StringTokenizer st = new StringTokenizer(candidato1,",");
//		this.showInfo("GetPuntoTempRaster: token " +candidato1);
//	    Point matchPoint = new Point();
//	    matchPoint.x = Integer.parseInt(st.nextToken());
//	    matchPoint.y = Integer.parseInt(st.nextToken());
//	    this.showInfo("GetPuntoTempRaster: match point " +matchPoint);
//	    return matchPoint;
//	}
	
    private void showInfo(String s) {
		System.out.println(s);
	}
    
//	public TiledImage implemTempIterators(PlanarImage imagen, PlanarImage template){
//		TemplateMatchingWithIterators tmr = new TemplateMatchingWithIterators(imagen, template); 
//		tmr.run();
//		TiledImage tim = tmr.getOutput();
//		return tim;
//	}
	
	public int[] colorPromedio(Image im){
		BufferedImage reticula = this.toBufferedImage(im);
		int sumatoriaR=0;
		int sumatoriaG=0;
		int sumatoriaB=0;
		int[] promedio = new int[3];
		int argb,r,b,g;
		for( int x=0; x < reticula.getWidth(); x=x+1 ){
			for( int y=0; y < reticula.getHeight(); y=y+1 ){
				argb = reticula.getRGB(x, y);
				r = 0xff & (argb>>16);
				g = 0xff & (argb >>8);
				b = 0xff & argb;
				sumatoriaR+=r;
				sumatoriaG+=g;
				sumatoriaB+=b;
			}
		}
		promedio[0]=Math.round(sumatoriaR / (reticula.getWidth() * reticula.getHeight() ));
		promedio[1]=Math.round(sumatoriaG / (reticula.getWidth() * reticula.getHeight() ));
		promedio[2]=Math.round(sumatoriaB / (reticula.getWidth() * reticula.getHeight() ));
		return promedio;
	}
	
	public BufferedImage convertToGrayscale(BufferedImage source) { 
	     BufferedImageOp op = new ColorConvertOp(
	       ColorSpace.getInstance(ColorSpace.CS_GRAY), null); 
	     return op.filter(source, null);
	}
	public String listarGris(Image im) {
		String cadena="";
		BufferedImage ib = this.toBufferedImage(im);
		BufferedImageOp op = new ColorConvertOp(
			       ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
		ib = op.filter(ib, null);
		try {
			for( int i=0; i < (ib.getHeight()); i=i+10 ){
				for( int j=0; j < (ib.getWidth()); j=j+10 ){
					cadena=cadena+"\n"+("pixel " +j+","+i+": "+ ib.getRGB(j, i));
				}
			}
			cadena= cadena+"\n"+("ancho: "+ib.getWidth()+", alto: "+ib.getHeight());
		}catch(Exception e){
			System.out.println(e);
			}
			return cadena;	
		}
	
//	public Image recortarImagenSeleccion(int x, int y, int w, int h,Image im){
//		recorteSelectivo tijera = new recorteSelectivo();
//		Image corte = tijera.cortarSeleccion(x, y, w, h, im);
//		return corte;
//	}
//
//	public Image recortarImagenCentro(int w, int h,Image im){
//		recorteSelectivo tijera = new recorteSelectivo();
//		Image corte = tijera.cortarCentro(w, h, im);
//		return corte;
//	}

	public BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage)image;
        }
    
        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();
    
        // Determine if the image has transparent pixels; for this method's
        // implementation, see e661 Determining If an Image Has Transparent Pixels
        boolean hasAlpha = hasAlpha(image);
    
        // Create a buffered image with a format that's compatible with the screen
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
            // Determine the type of transparency of the new buffered image
            int transparency = Transparency.OPAQUE;
            if (hasAlpha) {
                transparency = Transparency.BITMASK;
            }
    
            // Create the buffered image
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(
                image.getWidth(null), image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        }
    
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            if (hasAlpha) {
                type = BufferedImage.TYPE_INT_ARGB;
            }
            bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
        }
    
        // Copy image to buffered image
        Graphics g = bimage.createGraphics();
    
        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();
    
        return bimage;
    }
	
	public static boolean hasAlpha(Image image) {
        // If buffered image, the color model is readily available
        if (image instanceof BufferedImage) 
        {return ((BufferedImage)image).getColorModel().hasAlpha();}
    
        // Use a pixel grabber to retrieve the image's color model;
        // grabbing a single pixel is usually sufficient
        PixelGrabber pg = new PixelGrabber(image, 0, 0, 1, 1, false);
        try {
        	pg.grabPixels();
        } catch (InterruptedException e) {
        	System.out.println("no tiene alfa: "+e.getMessage());
        }
        // Get the image's color model
        return pg.getColorModel().hasAlpha();
    }
	public String analisis(Image im) {
		String cadena="";
		BufferedImage ib = this.toBufferedImage(im);
		int argb,r,b,g;
		try {
			for( int i=0; i < (ib.getHeight()); i=i+10 ){
				for( int j=0; j < (ib.getWidth()); j=j+10 ){
					argb = ib.getRGB(j, i);
					r = 0xff & (argb>>16);
					g = 0xff & (argb >>8);
					b = 0xff & argb;
					cadena=cadena+"\n"+("pixel " +j+","+i+ 
						" ; verde: " + g +
						" ; rojo: " + r+
						" ; Azul: " + b);
				}
			}
			cadena= cadena+"\n"+("ancho: "+ib.getWidth()+", alto: "+ib.getHeight());
		}catch(Exception e){
			System.out.println(e);
			}
			return cadena;	
		}
/**
 * carga y obtiene la lista de algoritmos apra trabajar
 */
	/*public Vector getTotal() {
		this.listaAlgoritmos = new Vector();
		this.listaAlgoritmos.add("convertToGrayscale");
		this.listaAlgoritmos.add("recortarImagenCentro");
		this.listaAlgoritmos.add("recortarImagenSeleccion");
		this.listaAlgoritmos.add("listarGrises");
		this.listaAlgoritmos.add("crearMosaico");
		this.listaAlgoritmos.add("buscarObjeto");
		this.listaAlgoritmos.add("getPromedios");
		this.listaAlgoritmos.add("implemTempRasters");
		this.listaAlgoritmos.add("implemTempIterators");
		this.listaAlgoritmos.add("GetCandTempRaster");
		this.listaAlgoritmos.add("setTemplate");
		this.listaAlgoritmos.add("getTemplate");
		return this.listaAlgoritmos;
	}*/

	public void listarPromedios(int[][][] promedio){
		for( int x=0; x < promedio.length; x++ ){
			for( int y=0; y < promedio[0].length; y++ ){
				System.out.println(
				"bloque usado "+x+","+y+
				" R="+promedio[x][y][0]+
				" G="+promedio[x][y][1]+
				" B="+promedio[x][y][2]);
			}
		}
	}

//public void buscarObjeto(Image im, int ancho, int alto, int sizeCuadro) {
//	BufferedImage bi = this.toBufferedImage(im);
//	int [][][] listaPromedios = this.getPromedios(im, sizeCuadro);
//	System.out.println("imagen");
//	listarPromedios(listaPromedios);
//	Image recorteCentro = this.recortarImagenCentro(ancho, alto, im);
//	int [][][] listaPromediosCentro = this.getPromedios(recorteCentro,sizeCuadro);
//	System.out.println("recorte");
//	listarPromedios(listaPromediosCentro);
//}



private int[] cuadrosCentro(int sizeCuadro, int largo,int imAlto,int imAncho) {
	
	int cantCuadros = Math.round(largo / sizeCuadro);
	int[]lista = new int[cantCuadros+1];
	
	return lista;
}

//public int[][][] getPromedios(Image im, int tamanio){
//	BufferedImage bi = this.toBufferedImage(im);
//	int cantCuadrosAlto = 1+(Math.round(bi.getHeight()/tamanio));
//	int cantCuadrosAncho =1+(Math.round(bi.getWidth()/tamanio));
//	System.out.println(
//			"cuadros ancho "+cantCuadrosAncho + ", alto " + cantCuadrosAlto);
//	int[][][] listaPromedios = new int[cantCuadrosAncho][cantCuadrosAlto][3];
//	System.out.println("largos " + listaPromedios.length+
//			"," + listaPromedios[0].length+
//			"," + listaPromedios[0][0].length);
//			
//	if (im==null){
//		System.out.println("im es nulo, ProcesamientoDeImagenes.crearMosaico");
//		return null;
//	}
//	int posY=0;
//	int posX = 0;
//	int ancho =bi.getWidth();
//	int alto = bi.getHeight();
//	int altoCorte=0;
//	int anchoCorte=0;
//	int[] promedio = new int[3];
//	int numCuadAlto = 0;
//	int numCuadAncho = 0;
//	for( int x=0; x < ancho; x++ ){
//		if(posX>ancho){
//			x=ancho;
//			numCuadAncho=0;
//		}else{
//			numCuadAncho++;
//		}
//		for( int y=0; y  < alto; y++ ){
//			posY= y * tamanio;
//			posX= x * tamanio;
//			if(posY>alto){
//				y=alto;
//				numCuadAlto=0;
//			}else{
//				numCuadAlto++;
//			}
//			if ((posY<alto)&&(posX<ancho)){
//				anchoCorte = ancho - posX;
//				altoCorte = alto - posY;
//				if(anchoCorte>tamanio){
//					anchoCorte=tamanio;
//				}else if(anchoCorte ==0){
//					anchoCorte=1;
//				}
//				if(altoCorte>tamanio){
//					altoCorte=tamanio;
//				}else if(altoCorte ==0){
//					altoCorte=1;
//				}
//				
//				promedio = this.colorPromedio(
//						this.recortarImagenSeleccion(
//								posX, posY, anchoCorte, altoCorte, im));
//				listaPromedios[numCuadAncho-1][numCuadAlto-1][0]= promedio[0];
//				listaPromedios[numCuadAncho-1][numCuadAlto-1][1]= promedio[1];
//				listaPromedios[numCuadAncho-1][numCuadAlto-1][2]= promedio[2];
//			}
//		}
//	}
//	return listaPromedios;
//}


//	public Vector GetCandTempRaster(PlanarImage pimGrande) {
//		TemplateMatchingWithRasters tmr = new TemplateMatchingWithRasters(pimGrande, template); 
//		tmr.templateMatch();
//		return tmr.getCanditatos();
//	}

}
